home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / xrf.com / XRF_V123.C < prev    next >
Encoding:
Text File  |  1988-10-10  |  25.8 KB  |  828 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.  *  XRF  input file  output file  [/s]                                      *
  4.  *                                                                          *
  5.  *  Source file name: XRF_V123.C                                            *
  6.  *                                                                          *
  7.  *    DESCRIPTION:                                                          *
  8.  *                                                                          *
  9.  *                    Cross Reference & Block Structure                     *
  10.  *                    Version 1.23     October 10, 1988                     *
  11.  *                                                                          *
  12.  *    'XRF' is a cross-reference block-structure program                    *
  13.  *    written in C for C and similar languages.  It has the                 *    
  14.  *    following features:                                                   *
  15.  *                                                                          *
  16.  *    1) Single spaced cross-reference list                                 *
  17.  *                                                                          *
  18.  *    2) Block structure in output program,                                 *
  19.  *       nested blocks included                                             *
  20.  *                                                                          *
  21.  *    3) Removal of tabs in output file as some printers                    *
  22.  *       don't support them                                                 *
  23.  *                                                                          *
  24.  *    4) Strip white space from end of lines in output files                *
  25.  *                                                                          *
  26.  *    5) Works on C or Telix SALT script source files                       *
  27.  *                                                                          *
  28.  *                                                                          *
  29.  *    FUNCTIONS:                                                            *
  30.  *                                                                          *
  31.  *    Function        Description                                           *
  32.  *    --------        -----------                                           *
  33.  *    get_token       Returns a valid identifier or reserved word.          *
  34.  *    getch           Returns a character from the character buffer         *
  35.  *                     and when ready for new line prints line to file.     *
  36.  *    ungetch         Puts the character optained by getch back in          *
  37.  *                     the character buffer.                                *
  38.  *    getline         Gets a line of text from a file, removes tabs,        *
  39.  *                     and removes white space from the end of the line.    *
  40.  *    ungetline       Puts a line of text in the character buffer.          *
  41.  *    checktoken      Compares the token with Beginning and end of          *
  42.  *                     block characters.                                    *
  43.  *    in_comment      Skips over comments in a file.                        *
  44.  *    in_salt_comment Skips over comments in a SALT file.                   *
  45.  *    in_quote        Skips over quotes in a file.                          *
  46.  *    in_salt_quote   Skips over quotes in a SALT file.                     *
  47.  *    line_hdr        Puts dashes in place of leading blanks on the         *
  48.  *                     front of a line.                                     *
  49.  *    block_line_hdr  Puts block information in front of the line           *
  50.  *                     and adds a new line to the output file.              *
  51.  *    page_hdr        Puts a header on each page.                           *
  52.  *    type            Reutrns the type of character LETTER, DIGIT,          *
  53.  *                     other.                                               *
  54.  *    strsave         Saves a string in memory.                             *
  55.  *    treex           Puts tokens and line numbers in a binary tree.        *
  56.  *    treexprint      Prints out the tree to a file.                        *
  57.  *    add_line_num    Puts a linenumber in the tree at the token it         *
  58.  *                     goes with.                                           *
  59.  *    treenewline     Adds a new line of tree token and numbers to the      *
  60.  *                     output file.                                         *
  61.  *    list_alloc      Makes space for the linked list.                      *
  62.  *    tree_alloc      Makes space for the tree nodes.                       *
  63.  *                                                                          *
  64.  ****************************************************************************
  65.  *                                                                          *
  66.  *   Revision history:                                                      *
  67.  *                                                                          *
  68.  *     v1.00 by Jay B. Bronaugh - 10/12/87                                  *
  69.  *           for C Programming class @ Phoenix College                      *
  70.  *           only exists as photocopied listing                             *
  71.  *           original name CCR                                              *
  72.  *                                                                          *
  73.  *     v1.01 by Tom Goodgame - 09/25/88                                     *
  74.  *           typed in from listing using personal style                     *
  75.  *           changed declaration of character variables from int to char    *
  76.  *                                                                          *
  77.  *     v1.10 by Tom Goodgame - 09/26/88                                     *
  78.  *           added code to allow use on Telix v3.0 SALT scripts             *
  79.  *             modified get_token, added in_salt_comment & in_salt_quote    *
  80.  *           added code for output to test file during debugging            *
  81.  *             currently commented out                                      *
  82.  *                                                                          *
  83.  *     v1.20 by Tom Goodgame - 09/27/88                                     *
  84.  *           change user interface so that USAGE line is shown when there   *
  85.  *             are no parameters supplied, instead of prompting for the     *
  86.  *             file names                                                   *
  87.  *           add sensing of command line switches, first switch to be       *
  88.  *             added will be for indicating that input file is a Telix      *
  89.  *             SALT script (instead of relying on detection of SALT type    *
  90.  *             comments)                                                    *
  91.  *           fixed ALL compiler warnings                                    *
  92.  *           Added BOOLEAN type for flags (specialized int) in boolean.h    *
  93.  *                                                                          *
  94.  *     v1.21 by Tom Goodgame - 09/28/88                                     *
  95.  *           bug created by overchecking comment syntax caused "syntax"     *
  96.  *             error when faced with a divide (i.e., x/y)                   *
  97.  *                                                                          *
  98.  *     v1.22 by Tom Goodgame - 10/02/88                                     *
  99.  *           change appearance of Copyright notice                          *
  100.  *           improved variable naming                                       *
  101.  *           improved message text from errors                              *
  102.  *           changed test for /s switch so it looked for both upper and     *
  103.  *             lower case 's'.                                              *
  104.  *                                                                          *
  105.  *     v1.23 by Tom Goodgame - 10/10/88                                     *
  106.  *           get version number correct in USAGE output                     *
  107.  *                                                                          *
  108.  *     Planned for version 1.30 is auto line wrap.  Currently lines can     *
  109.  *       be 256 characters long and there is no attempt to wrap them.  The  *
  110.  *       program was originally written around a 132 character printer      *
  111.  *       width.  Input lines greater than 80 characters will run off the    *
  112.  *       edge of the paper or be wrapped by the printer.                    *
  113.  *                                                                          *
  114.  *     Planned for v2.xx will be parameter files for syntax, keywords,      *
  115.  *       etc. with a different set for each language so the program will    *
  116.  *       be useable with any language and keywords will be separated        *
  117.  *       from functions and variables.                                      *
  118.  *                                                                          *
  119.  ****************************************************************************
  120.  *                                                                          *
  121.  *     Copyright (C) 1988 by Thomas H. Goodgame, Jr. - all rights reserved  *
  122.  *                                                                          *
  123.  *     Source code and executable modules are freely useable and            *
  124.  *     distributable, subject to the following five conditions:             *
  125.  *                                                                          *
  126.  *     1)    If they are included with a commercial package, no changes      *
  127.  *          may be made to the source, they must be distributed in their    *
  128.  *          entirety, and no charge can be made for these programs.         *
  129.  *                                                                          *
  130.  *     2)    If they are distributed by a public domain/freeware/shareware   *
  131.  *          distribution organization (PC-SIG, user group, etc.) the        *
  132.  *          charge per diskette of programs must not exceed six dollars     *
  133.  *          ($6).  All files must be distributed together on one disk and   *
  134.  *          preferably in one library or archive file.                      *
  135.  *                                                                          *
  136.  *     3)    If they are distributed by BBS, no additional charges above     *
  137.  *          and beyond the connection charge (if any) may be made.  All     *
  138.  *          files must be distributed together in one library or archive    *
  139.  *          file.                                                           *
  140.  *                                                                          *
  141.  *     4)    Individuals and educational institutions may distribute these   *
  142.  *          programs without charge.  They may also modify the source for   *
  143.  *          their purposes so long as attribution is made.  They should     *
  144.  *          also indicate what the changes were, whom by, and the date.     *
  145.  *          Copyright should be asserted to prevent the code from going     *
  146.  *          public domain and then being commercialized.                    *
  147.  *                                                                          *
  148.  *     5)    Any other distribution not directly covered, must be made in    *
  149.  *          the spirit of the above conditions.                             *
  150.  *                                                                          *
  151.  *     Contact: Tom Goodgame via CompuServe UserID 76327,2053               *
  152.  *                                                                          *
  153.  *                  or                                                      *
  154.  *                                                                          *
  155.  *              Tom Goodgame via Flying Circus BBS    (602) 437-1301        *
  156.  *                               CentraLink BBS       (602) 254-9031        *
  157.  *                               Inn on the Park BBS  (602) 957-0631        *
  158.  *                               ASU Underground BBS  (602) 968-2814        *
  159.  *                               Tool Shop BBS        (602) 279-2673        *
  160.  *                                                                          *
  161.  *                  or                                                      *
  162.  *                                                                          *
  163.  *              Thomas Goodgame via Phoenix PCUG BBS  (602) 275-5558        *
  164.  *                                                                          *
  165.  *                                                                          *
  166.  ****************************************************************************/
  167.  
  168.  
  169. #include <stdio.h>
  170. #include <stdlib.h>
  171. #include <string.h>
  172. #include <boolean.h>
  173.  
  174. /*************
  175.  * constants *
  176.  *************/
  177.  
  178. #define TAB_SPACE         8
  179. #define LETTER            'a'
  180. #define DIGIT             '0'
  181. #define MAX_WORD_LENGTH   32
  182. #define FORM_FEED         '\014'
  183. #define PRINT_LINES       52
  184. #define MAX_NUM_BLOCKS    20
  185. #define MAX_LINE_LENGTH   256
  186. #define BUFFER_SIZE       256
  187. #define PROGNAME          "Cross Reference & Block Structure"
  188. #define COPYRIGHT         "Copyright (C) 1988 by Thomas H. Goodgame, Jr. \
  189. - all rights reserved"   
  190. #define VERSION           "ver 1.23"
  191. #define VER_DATE          "10/10/1988"
  192.  
  193. /**************
  194.  * structures *
  195.  **************/
  196.  
  197. struct linklist
  198.  {
  199.  int lnum;
  200.  struct linklist *ptr;
  201.  };
  202.  
  203. struct tnode
  204.  {
  205.  char *word;
  206.  struct linklist *lines;
  207.  struct tnode *left;
  208.  struct tnode *right;
  209.  };
  210.  
  211. /********************
  212.  * global variables *
  213.  ********************/
  214.  
  215. FILE *infile;
  216. FILE *outfile;
  217. /* FILE *tstfile; */
  218.  
  219. char inname[MAX_LINE_LENGTH];
  220. char outname[MAX_LINE_LENGTH];
  221. /* char tstname[]                  = "test.fil"; */
  222.  
  223. char sw_strn[MAX_LINE_LENGTH];
  224. char line[MAX_LINE_LENGTH];
  225.  
  226. BOOLEAN is_salt                 = FALSE;     /* File is a Telix SALT script */
  227. BOOLEAN switches                = FALSE;        /* Switch argument supplied */
  228.  
  229. char buffer[BUFFER_SIZE];
  230. int buffer_position             = 0;
  231. int line_number                 = 0;
  232. int token_number                = 0;
  233. int page_number                 = 0;
  234. int blocks                      = 0;
  235. int totalblocks                 = 0;
  236. int blocknest                   = 0;
  237. char block                      = ' ';
  238.  
  239. /***********************
  240.  * function prototypes *
  241.  ***********************/
  242.  
  243. int getline(char *, int);
  244. void ungetch(char);
  245. void ungetline(char []);
  246. void line_hdr(char *);
  247. void block_line_hdr(void);
  248. void page_hdr(void);
  249. char getch(void);
  250. int type(char);
  251. void in_comment(void);
  252. void in_salt_comment(void);
  253. void in_quote(char);
  254. void in_salt_quote(char);
  255. void checktoken(char *);
  256. int get_token(char *, int);
  257. struct linklist *list_alloc(void);
  258. struct tnode *tree_alloc(void);
  259. char *strsave(char *);
  260. void add_line_num(struct tnode *, int);
  261. struct tnode *treex(struct tnode *, char *, int);
  262. void treenewline(void);
  263. void treexprint(struct tnode *);
  264. int main(int, char * []);
  265.  
  266. /***********
  267.  * getline *
  268.  ***********/
  269.   
  270. int getline(s, lim)
  271.  char *s;
  272.  int lim;
  273.  {
  274.  int c;
  275.  int nb = 0;
  276.  int pos = 1;
  277.  
  278.  while (--lim > 0 && (c = getc(infile)) != EOF && c != '\n')
  279.   if (c == '\t')
  280.     {
  281.     nb = TAB_SPACE - (pos - 1) % TAB_SPACE;
  282.     while (nb > 0)
  283.      {
  284.      *s++ = ' ';
  285.      ++pos;
  286.      --nb;
  287.      }
  288.     }
  289.    else
  290.     {
  291.     *s++ = (char)c;
  292.     ++pos;
  293.     }
  294.  if (lim == 0)
  295.    {
  296.    fprintf(stderr, "FATAL ERROR: Line longer than %d characters\n",
  297.                        MAX_LINE_LENGTH);
  298.    exit(1);
  299.    }
  300.  *s--;
  301.  if (*s == ' ')
  302.    {
  303.    while (*s == ' ')
  304.     *s--;
  305.    *s--;
  306.    *s++;
  307.    }
  308.  *s++;
  309.  *s++ = (char)c;
  310.  *s = NULL;
  311.  if (c == EOF)
  312.    return(EOF);
  313.  return(0);
  314.  }
  315.  
  316. /***********
  317.  * ungetch *
  318.  ***********/
  319.  
  320. void ungetch(c)
  321.  char c;
  322.  {
  323.  if (buffer_position > BUFFER_SIZE)
  324.    {
  325.    fprintf(stderr, "FATAL ERROR: Buffer overflow\n");
  326.    exit(1);
  327.    }
  328.   else
  329.    buffer[buffer_position++] = c;
  330.  }
  331.  
  332. /*************
  333.  * ungetline *
  334.  *************/
  335.  
  336. void ungetline(s)
  337.  char s[];
  338.  {
  339.  int len = strlen(s);
  340.  
  341.  while (len > 0)
  342.   ungetch(s[--len]);
  343.  }
  344.  
  345. /************
  346.  * line_hdr *
  347.  ************/
  348.  
  349. void line_hdr(s)
  350.  char *s;
  351.  {
  352.  char c;
  353.  
  354.  while (*s == ' ')
  355.   if (*s == ' ')
  356.     *s++ = '-';
  357.  }
  358.  
  359. /******************
  360.  * block_line_hdr *
  361.  ******************/
  362.  
  363. void block_line_hdr()
  364.  {
  365.  int blk;
  366.  
  367.  fprintf(outfile, "%4d    ", line_number);
  368.  printf("%4d\r", line_number);
  369.  switch (block)
  370.   {
  371.   case 'S' :
  372.    for (blk = 0; blk < blocks; ++blk)
  373.     fprintf(outfile, "| ");
  374.    fprintf(outfile, "%c", block);
  375.    for (blk = 0; blk < (MAX_NUM_BLOCKS - blocks); ++blk)
  376.     fprintf(outfile, "--");
  377.    blocks += (blocknest - blocks);
  378.    block = ' ';
  379.    line_hdr(line);
  380.    break;
  381.   case 'E' :
  382.    blocks += (blocknest - blocks);
  383.    for (blk = 0; blk < blocks; ++blk)
  384.     fprintf(outfile, "| ");
  385.    fprintf(outfile, "%c", block);
  386.    for (blk = 0; blk < (MAX_NUM_BLOCKS - blocks); ++blk)
  387.     fprintf(outfile, "--");
  388.    block = ' ';
  389.    line_hdr(line);
  390.    break;
  391.   default :
  392.    for (blk = 0; blk < blocks; ++blk)
  393.     fprintf(outfile, "| ");
  394.    fprintf(outfile, "%c", block);
  395.    for (blk = 0; blk < (MAX_NUM_BLOCKS - blocks); ++blk)
  396.     fprintf(outfile, "  ");
  397.   }
  398.  }
  399.  
  400. /************
  401.  * page_hdr *
  402.  ************/
  403.  
  404. void page_hdr()
  405.  {
  406.  fprintf(outfile, "\%c", FORM_FEED);
  407.  fprintf(outfile, "\n\n\n\n\n\n");
  408.  fprintf(outfile, " \%-12s", inname);
  409.  fprintf(outfile, "                               ");
  410.  fprintf(outfile, "%s %s", PROGNAME, VERSION);
  411.  fprintf(outfile, "                               ");
  412.  fprintf(outfile, "Page %4d\n\n", ++page_number);
  413.  }
  414.  
  415. /*********
  416.  * getch *
  417.  *********/
  418.  
  419. char getch()
  420.  {
  421.  if (buffer_position > 0)
  422.    return(buffer[--buffer_position]);
  423.   else
  424.    {
  425.    if (line_number != 0)
  426.      block_line_hdr();
  427.    fprintf(outfile, "%s", line);
  428.    if ((line_number % PRINT_LINES) == 0)
  429.      page_hdr();
  430.    if ((getline(line, MAX_LINE_LENGTH)) != EOF)
  431.      line_number++;
  432.    ungetline(line);
  433.    return(getch());
  434.    }
  435.  }
  436.  
  437. /********
  438.  * type *
  439.  ********/
  440.  
  441. int type(c)
  442.  char c;
  443.  {
  444.  if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_')
  445.    return(LETTER);
  446.   else if (c >= '0' && c <= '9')
  447.    return(DIGIT);
  448.   else
  449.    return(c);
  450.  }
  451.  
  452. /**************
  453.  * in_comment *
  454.  **************/
  455.  
  456. void in_comment()
  457.  {
  458.  char c, ch;
  459.  
  460.  c = getch();
  461.  ch = getch();
  462.  while (c != '*' || ch != '/')
  463.   {
  464.   c = ch;
  465.   ch = getch();
  466.   }
  467.  }
  468.  
  469. /*******************
  470.  * in_salt_comment *
  471.  *******************/
  472.  
  473.  void in_salt_comment()
  474.  {
  475.  char c;
  476.  
  477.  c = getch();
  478.  while (c != '\n')
  479.   {
  480.   c = getch();
  481.   }
  482.  ungetch(c);
  483.  }
  484.  
  485. /************
  486.  * in_quote *
  487.  ************/
  488.  
  489. void in_quote(c)
  490.  char c;
  491.  {
  492.  char ch;
  493.  
  494.  while ((ch = getch()) != c)
  495.   if (ch == '\\')
  496.     getch();
  497.  }
  498.  
  499. /*****************
  500.  * in_salt_quote *
  501.  *****************/
  502.  
  503. void in_salt_quote(c)
  504.  char c;
  505.  {
  506.  char ch;
  507.  
  508.  while ((ch = getch()) != c);
  509.  }
  510.  
  511. /**************
  512.  * checktoken *
  513.  **************/
  514.  
  515. void checktoken(t)
  516.  char *t;
  517.  {
  518.  if (strcmp(t, "{") == 0)
  519.    {
  520.    block = 'S';
  521.    blocknest++;
  522.    totalblocks++;
  523.    }
  524.  if (strcmp(t, "}") == 0)
  525.    {
  526.    block = 'E';
  527.    blocknest--;
  528.    }
  529.  }
  530.  
  531. /*************
  532.  * get_token *
  533.  *************/
  534.  
  535. int get_token(w, lim)
  536.  char *w;
  537.  int lim;
  538.  {
  539.  char c;
  540.  int t;
  541.  
  542.  if ((t = type(c = *w++ = getch())) != LETTER)
  543.    {
  544.    if (c == '/')
  545.      {
  546.      c = getch();
  547.      if (c == '*'&& is_salt == FALSE)
  548.        in_comment();
  549.       else if (c == '/' && is_salt == TRUE)
  550.        in_salt_comment();
  551.       else if (c == '*' && is_salt == TRUE || c == '/' && is_salt == FALSE)
  552.        {
  553.        fprintf(stderr, "FATAL ERROR: Improper comment syntax, line = %4d\n",
  554.            line_number);
  555.        exit(5);       
  556.        }
  557.      }
  558.    if (c == '\'' || c == '\"')
  559.      if (is_salt == TRUE)
  560.        in_salt_quote(c);
  561.       else
  562.        in_quote(c);
  563.     *w = '\0';
  564.    return(c);
  565.    }
  566.  while (--lim > 0)
  567.   {
  568.   t = type(c = *w++ = getch());
  569.   if (t != LETTER && t != DIGIT)
  570.     {
  571.     ungetch(c);
  572.     break;
  573.     }
  574.   }
  575.  *(w-1) = '\0';
  576.  return(LETTER);
  577.  }
  578.  
  579. /**************
  580.  * list_alloc *
  581.  **************/
  582.  
  583. struct linklist *list_alloc()
  584.  {
  585.  return((struct linklist *) malloc(sizeof(struct linklist)));
  586.  }
  587.  
  588. /**************
  589.  * tree_alloc *
  590.  **************/
  591.  
  592.  struct tnode *tree_alloc()
  593.  {
  594.  return((struct tnode *) malloc(sizeof(struct tnode)));
  595.  }
  596.  
  597. /***********
  598.  * strsave *
  599.  ***********/
  600.  
  601. char *strsave(s)
  602.  char *s;
  603.  {
  604.  char *p;
  605.  
  606.  if ((p = malloc(strlen(s) + 1)) != NULL)
  607.    strcpy(p, s);
  608.  return(p);
  609.  }
  610.  
  611. /****************
  612.  * add_line_num *
  613.  ****************/
  614.  
  615. void add_line_num(p, line_number)
  616.  struct tnode *p;
  617.  int line_number;
  618.  {
  619.  struct linklist *temp, *list_alloc();
  620.  
  621.  temp = p -> lines;
  622.  while (temp -> ptr != NULL && temp -> lnum != line_number)
  623.   temp = temp -> ptr;
  624.  if (temp -> lnum != line_number)
  625.    {
  626.    temp -> ptr         = list_alloc();
  627.    temp -> ptr -> lnum = line_number;
  628.    temp -> ptr -> ptr  = NULL;
  629.    }
  630.  }
  631.  
  632. /*********
  633.  * treex *
  634.  *********/
  635.  
  636. struct tnode *treex(p, w, line_number)
  637.  struct tnode *p;
  638.  char *w;
  639.  int line_number;
  640.  {
  641.  struct tnode *tree_alloc();
  642.  struct linklist *list_alloc();
  643.  char *strsave();
  644.  int cond;
  645.  
  646.  if (p == NULL)
  647.    {
  648.    p                  = tree_alloc();
  649.    p -> word          = strsave(w);
  650.    p -> lines         = list_alloc();
  651.    p -> lines -> lnum = line_number;
  652.    p -> lines -> ptr  = NULL;
  653.    p -> left          = p -> right  = NULL;
  654.    }
  655.   else if ((cond = strcmp(w, p -> word)) == 0)
  656.    add_line_num(p, line_number);
  657.   else if (cond > 0)
  658.    p -> left = treex(p -> left, w, line_number);
  659.   else
  660.    p -> right = treex(p -> right, w, line_number);
  661.  return(p);
  662.  }
  663.  
  664. /***************
  665.  * treenewline *
  666.  ***************/
  667.  
  668. void treenewline()
  669.  {
  670.  ++token_number;
  671.  fprintf(outfile, "\n");
  672.  if ((token_number % PRINT_LINES) == 0)
  673.    page_hdr();
  674.  }
  675.  
  676. /**************
  677.  * treexprint *
  678.  **************/
  679.  
  680. void treexprint(p)
  681.  struct tnode *p;
  682.  {
  683.  struct linklist *temp;
  684.  int dots, num, gap;
  685.  
  686.  if (p != NULL)
  687.    {
  688.    treexprint(p -> right);
  689.    fprintf(outfile, "%s", p -> word);
  690.    for (dots = 0; dots < (MAX_WORD_LENGTH - (strlen(p -> word))); dots++)
  691.     fprintf(outfile, ".");
  692.    for (temp = p -> lines, num = 1; temp != NULL; temp = temp -> ptr, ++num)
  693.     {
  694.     fprintf(outfile, " %4d ", temp -> lnum);
  695.     if ((num % 16) == 0)
  696.       {
  697.       treenewline();
  698.       for (gap = 0; gap < MAX_WORD_LENGTH; gap++)
  699.        fprintf(outfile, " ");
  700.       }
  701.     }
  702.    treenewline();
  703.    treexprint(p -> left);
  704.    }
  705.  }
  706.  
  707. /********
  708.  * main *
  709.  ********/
  710.  
  711. main(argc,argv)
  712.  int argc;
  713.  char *argv[];
  714.  {
  715.  struct tnode *root, *treex();
  716.  char word[MAX_WORD_LENGTH];
  717.  int t;
  718.  
  719.  fprintf(stderr, "%s                   %s %-10s\n", PROGNAME, VERSION,
  720.      VER_DATE);
  721.  fprintf(stderr, "    %s\n\n", COPYRIGHT);
  722.  
  723.  if (argc >= 3)
  724.    {
  725.    strcpy(inname, argv[1]);
  726.    strcpy(outname, argv[2]);
  727.    }
  728.   else
  729.    {
  730.    fprintf(stderr, "\n");
  731.    fprintf(stderr, "   USAGE: XRF [input file] [output file] /switch(es)\n");
  732.    fprintf(stderr, "     [input file]   required\n");
  733.    fprintf(stderr, "     [output file]  required\n");
  734.    fprintf(stderr, "     /switch(es)    optional\n");
  735.    fprintf(stderr, "       /s - input file is Telix SALT script\n");
  736.    fprintf(stderr, "\n");
  737.    fprintf(stderr, "   ERRORLEVEL return codes:\n");
  738.    fprintf(stderr, "     0 - successful\n");
  739.    fprintf(stderr, "     1 - line too long or buffer overflow\n");
  740.    fprintf(stderr, "     2 - could not open file\n");
  741.    fprintf(stderr, "     3 - input and output files the same\n");
  742.    fprintf(stderr, "     4 - no arguments supplied (produced this screen)\n");
  743.    fprintf(stderr, "     5 - improper comment syntax\n");
  744.    fprintf(stderr, "\n");
  745.    exit(4);
  746.    }
  747.  
  748.  
  749.  if (argc > 4)
  750.    fprintf(stderr, "NON-FATAL ERROR: Excess arguments suppled on command line"
  751.                        " were ignored");
  752.  
  753.  if (argc >= 4)
  754.    {
  755.    strcpy(sw_strn, argv[3]);
  756.    switches = TRUE;
  757.    }
  758.  
  759.  if (switches == TRUE)
  760.    if (strlen(sw_strn) == 2)
  761.      if (strstr(sw_strn, "/s") != NULL || strstr(sw_strn, "/S") != NULL)
  762.        is_salt = TRUE;
  763.       else
  764.        fprintf(stderr, "NON-FATAL ERROR: Undefined switch %s entered - "
  765.                            "ignored\n", sw_strn);
  766.     else
  767.      fprintf(stderr,
  768.          "NON-FATAL ERROR: Switch argument not correct length - ignored\n");
  769.  
  770.  if (strcmp(inname, outname) == 0)
  771.    {
  772.    fprintf(stderr, "FATAL ERROR: Input and output files can't be the same\n");
  773.    exit(3);
  774.    }
  775.  
  776.  if ((infile = fopen(inname, "r")) == NULL)
  777.    {
  778.    fprintf(stderr, "FATAL ERROR: Unable to open input file %s\n", inname);
  779.    exit(2);
  780.    }
  781.  
  782.  if ((outfile = fopen(outname, "w")) == NULL)
  783.    {
  784.    fprintf(stderr, "FATAL ERROR: Unable to open output file %s\n", outname);
  785.    fclose(infile);
  786.    exit(2);
  787.    }
  788.  
  789. /*
  790.  if ((tstfile = fopen(tstname, "w")) == NULL)
  791.    {
  792.    fprintf(stderr, "FATAL ERROR: Unable to open test file %s\n", tstname);
  793.    fclose(infile);
  794.    fclose(outfile);
  795.    exit(2);
  796.    }
  797. */
  798.  
  799.  printf("\nReading from %s\n", inname);
  800.  printf("     Lines\r");
  801.  
  802.  root = NULL;
  803.  while ((t = get_token(word, MAX_WORD_LENGTH)) != EOF)
  804.   {
  805.   checktoken(word);
  806.   if (t == LETTER)
  807.     root = treex(root, word, line_number);
  808.   }
  809.  
  810.  page_hdr();
  811.  printf("\n\nWriting to %s\n", outname);
  812.  treexprint(root);
  813.  fprintf(outfile, "\%c", FORM_FEED);
  814.  fclose(infile);
  815.  fclose(outfile);
  816. /*
  817.  fclose(tstfile);
  818. */
  819.  printf("%4d Lines\n", (line_number + token_number));
  820.  printf("%4d References\n", token_number);
  821.  printf("%4d Blocks\n", totalblocks);
  822.  printf("%4d Pages\n", page_number);
  823.  exit(0);
  824.  return(0);
  825.  }
  826.  
  827.  
  828.